home *** CD-ROM | disk | FTP | other *** search
- /*
- File: OSLClAcc.c (Orignal name: OSLCallAccessor.c)
-
- Contains:
-
- Owned by: Nick Pilch
-
- Copyright: © 1993 - 1995 by Apple Computer, Inc., all rights reserved.
-
- Change History (most recent first):
-
- <7> 6/28/95 eeh 1262143: dispose swap token
- <6> 5/12/95 NP 1246047: OSL doesn't dispose tokens
- correctly when swapping.
- <5> 3/13/95 NP 1226003: Remove GetContainingFrame from the
- API. Don't null out user token.
- <4> 2/22/95 eeh 1222904: fix use of SetCurrentContext
- <3> 2/8/95 NP 1218550: Don't allocate OSLContexts
- dynamically.
- <2> 8/19/94 NP 1181622: Ownership fix.
- <17> 5/2/94 eeh bug #1160654: various PPC native changes
- <16> 2/7/94 NP Tiger Team doings.
- <15> 11/30/93 NP Added error checking.
- <14> 11/18/93 JA Made RecursiveCallObjectAccessor static
- (prevents missing-prototype error in THINK)
- <13> 11/2/93 NP Moved back pascal keyword for MPW C.
- <12> 11/2/93 NP Move pascal keyword.
- <11> 10/28/93 NP Fixed bug where switching contexts could
- only be done once. Is now a recursive
- routine.
- <10> 10/22/93 NP Removed obsolete context parameter from
- some functions.
- <9> 10/18/93 NP Added #pragma unused statements.
- <8> 10/11/93 NP Added DebugStr.
- <7> 9/10/93 NP Fixed some bugs.
- <6> 9/3/93 NP Use "switch" constant instead of
- hard-coded.
- <5> 8/18/93 NP Implemented for new context scheme.
- <4> 8/16/93 NP Adjusted for latest OSL proposal.
- <3> 7/28/93 NP Mods for new token type, OSLToken.
- <2> 7/21/93 NP Fixed #includes.
- <1> 7/21/93 NP first checked in
-
- To Do:
- */
-
- /*
- ©Apple Computer, Inc. 1992
- All Rights Reserved.
- Author: Eric House
- */
- #include <Errors.h>
-
- #ifndef _OSLPRIV_
- #include "OSLPriv.h"
- #endif
-
- #ifndef _CNTXTOSL_
- #include "CntxtOSL.h"
- #endif
-
- #ifndef _OSLTOKEN_
- #include "OSLToken.h"
- #endif
-
- #pragma segment AEObjSuppt
-
- pascal OSErr
- iAERemoveObjectAccessor( DescType desiredClass ,
- DescType containerType ,
- OSLAccessorUPP handler ,
- Boolean isSysHandler);
-
-
- // GetTableInfo()
- // find the handler and refcon for the corresponding key, wildcard is used
- // This is lifted directly from Ed's AEHandlerTable.inc1.p
- // NOTE: <eeh> this duplicates a function in the AEM. When we fold this into AEM
- // we need to take it out.
-
- static Boolean
- GetTableInfo( HHand theTable , //--> handle to table
- OSType key1, OSType key2 , // --> search these keys
- ObjectAccessorValue* theHandlerRec ) // <-- return this ProcPtr record }
- {
- ObjectAccessorKey theKeyRec ;
-
- Boolean result = true ;
- theKeyRec.firstKey = key1;
- theKeyRec.secondKey = key2;
-
- if ( AEGetKeyValue( theTable, NULL, (KeyPtr)&theKeyRec,
- (HEntryPtr)theHandlerRec ) != noErr )
- {
- theKeyRec.firstKey = typeWildCard ;
- if ( AEGetKeyValue( theTable, NULL, (KeyPtr)&theKeyRec,
- (HEntryPtr)theHandlerRec) != noErr )
- {
- theKeyRec.firstKey = key1;
- theKeyRec.secondKey = typeWildCard;
- if ( AEGetKeyValue( theTable, NULL, (KeyPtr)&theKeyRec,
- (HEntryPtr)theHandlerRec) != noErr )
- {
- theKeyRec.firstKey = typeWildCard;
- result = AEGetKeyValue( theTable, NULL, (KeyPtr)&theKeyRec,
- (HEntryPtr)theHandlerRec) == noErr ;
- }
- }
- }
- return result ;
- }
-
- // Recursively build a new range descriptor whose ccnt containers have been
- // replaced by the token container
-
- static OSErr
- DoSubst( AEDesc *theObj, ContainedTokenRecord *tokenRec,
- DescType containerClass, OSLToken dContainerToken ) //recurse until reach bottom }
- {
- AERecord dObjRecord ;
- AEDesc dTheContainer ;
- OSErr err;
-
- if ( theObj->descriptorType == typeObjectSpecifier )
- {
- err = AECoerceDesc( theObj, typeAERecord, &dObjRecord ) ;
- IgnoreOSErr( AEDisposeDesc( theObj ) ) ;
- if ( err != noErr ) goto L100 ;
-
- err = AEGetKeyDesc( &dObjRecord, keyAEContainer, typeWildCard,
- &dTheContainer ) ;
- if ( err != noErr ) goto L200 ;
-
- err = DoSubst( &dTheContainer, tokenRec, containerClass,
- dContainerToken ) ;
- if ( err != noErr ) goto L200 ;
-
- err = AEPutKeyDesc( &dObjRecord, keyAEContainer, &dTheContainer ) ;
- if ( err != noErr ) goto L300 ;
-
- err = AECoerceDesc( &dObjRecord, typeObjectSpecifier, theObj ) ;
-
- L300:
- IgnoreOSErr( AEDisposeDesc( &dTheContainer ) ) ;
- L200:
- IgnoreOSErr( AEDisposeDesc( &dObjRecord ) ) ;
- }
- else if ( theObj->descriptorType == typeCurrentContainer )
- {
- IgnoreOSErr( AEDisposeDesc( theObj ) ) ;
- tokenRec->tokenClass = containerClass ;
- tokenRec->token = dContainerToken ;
- err = AECreateDesc( typeToken, (Ptr)tokenRec, sizeof( *tokenRec ),
- theObj ) ;
- }
- else
- err = noErr ;
- L100:
- return err ;
- }
-
-
- static OSErr
- SubstContainerForccnt( OSLToken dContainerToken, DescType containerClass,
- AEDesc *rangeDesc )
- {
- AEDesc obj, dRangeRecord ;
- OSErr err ;
- ContainedTokenRecord tokenRec ;
-
-
- err = AECoerceDesc( rangeDesc, typeAERecord, &dRangeRecord ) ;
- if ( err != noErr ) goto L100 ;
-
- // IgnoreOSErr( AEDisposeDesc( rangeSelData ) ) ; { don't dispose: this is just a local copy }
-
- err = AEGetKeyDesc( &dRangeRecord, keyAERangeStart, typeWildCard, &obj ) ;
- if ( err != noErr ) goto L200 ;
-
- err = DoSubst( &obj, &tokenRec, containerClass, dContainerToken ) ;
- if ( err != noErr ) goto L200 ;
-
- err = AEPutKeyDesc( &dRangeRecord, keyAERangeStart, &obj ) ;
- IgnoreOSErr( AEDisposeDesc( &obj ) ) ;
- if ( err != noErr ) goto L200 ;
-
-
-
- err = AEGetKeyDesc( &dRangeRecord, keyAERangeStop, typeWildCard, &obj ) ;
- if ( err != noErr ) goto L200 ;
-
- err = DoSubst( &obj, &tokenRec, containerClass, dContainerToken ) ;
- if ( err != noErr ) goto L200 ;
-
- err = AEPutKeyDesc( &dRangeRecord, keyAERangeStop, &obj ) ;
- IgnoreOSErr( AEDisposeDesc( &obj ) ) ;
- if ( err != noErr ) goto L200 ;
-
- err = AECoerceDesc( &dRangeRecord, typeRangeDescriptor, rangeDesc ) ;
- L200:
- IgnoreOSErr( AEDisposeDesc( &dRangeRecord ) ) ;
- L100:
- return err ;
- }
-
-
-
- /*———————————————————————— TryAccessor ————————————————————————*/
-
- static OSErr
- TryAccessor( GlobalRecHandle aGlobalRef, Boolean *iFoundIt,
- OSLToken container, DescType wantType, AEDesc selectionData,
- DescType containerClass, DescType form, OSLToken *value )
- {
- OSErr err ;
- ObjectAccessorValue theValue ;
-
- err = errAEEventNotHandled ;
- if ( aGlobalRef != NULL )
- // WITH aGlobalRef** DO
- {
- GlobalRecPointer gp = *aGlobalRef ;
- if ( GetTableInfo( gp->accessorHashTable, wantType,
- container.descriptorType, &theValue ) )
- {
- // <eeh> need to check for NULL if don't check for NULL
- // when installing
- err = CallOSLAccessorProc( theValue.handler, wantType,
- &container, containerClass, form, &selectionData,
- value, theValue.handlerRefcon ) ;
- *iFoundIt = true ;
- }
- }
- return err ;
- } // TryAccessor
-
- /*———————————————————— RecursiveCallObjectAccessor ——————————————————————*/
-
- static
- OSErr RecursiveCallObjectAccessor( DescType wantType , OSLToken container ,
- DescType containerClass , DescType form,
- AEDesc selectionData , OSLToken *value, Boolean* iFoundIt,
- OSLContext* curContext )
- {
- OSLContext afterContext;
- OSErr err = noErr;
-
- err = (*(ObjectAccessorCaller)(*curContext->getCallerProc)
- (kObjectAccessor))
- (wantType, &container, containerClass, form, &selectionData, value,
- iFoundIt, curContext->refCon);
- // CONTEXT CHANGED?
- if (value->descriptorType == kSwitchDescType && (err == noErr))
- {
- // DISPOSE OLD CONTAINER TOKEN????
- err = OSLGetTokenContext(value, &afterContext);
- if (err)
- return err;
- err = SetCurrentContext(&afterContext);
- if (err)
- return err;
-
- // this will leak if not disposed now; it's done its job.
- iAEDisposeToken( value );
-
- // DISPOSE TOKEN???? PROBABLY.
- containerClass = typeNull;
- // THIS LINE BELOW DOESN'T SEEM TO WORK. THE DESCRIPTOR WILL GET DISPOSED
- // TWICE. ONCE HERE AND ONCE IN INTERNALRESOLVE (LOOK FOR DISPOSAL OF
- // dContainerToken.)
- // iAEDisposeToken(&container);
- MakeNullToken(&container);
- err = RecursiveCallObjectAccessor(wantType, container, containerClass,
- form, selectionData, value,
- iFoundIt, &afterContext);
- }
- return err;
- } /* RecursiveCallObjectAccessor */
-
- /*———————————————————————— iCallAccessor ————————————————————————*/
-
- pascal OSErr
- iCallAccessor( DescType wantType , OSLToken container ,
- DescType containerClass , DescType form,
- AEDesc selectionData , OSLToken *value )
- {
-
- OSErr err ;
- long nElements ;
- OSLContext curContext;
-
- // 5/13 This guy allows to distinguish between an access||NotFound
- // error and the case where there was an access|| but it returned
- //eventNotHandled (as when it decides it _does_ want me to do whoses). */
-
- Boolean madeACopy, iFoundIt ;
-
-
- err = noErr ;
- iFoundIt = false ;
-
- // if marking not being used and container is an empty list and we're not
- // looking for kAEAll of something then return error. If we do want all
- // then just return the empty list. Fixes LLD-???
-
- if ( container.descriptorType == typeAEList ) // type of 'list' assumes not a mark token. Tell Mitch
- {
- err = AECountItems( &container, &nElements ) ;
- if ( err != noErr )
- {
- return err ;
- }
- if ( nElements == 0 )
- {
- if ( (form == formAbsolutePosition)
- && (selectionData.descriptorType == typeAbsoluteOrdinal)
- && (**((DescTypeHandle)(selectionData.dataHandle)) == kAEAll) )
- {
- DebugStr("\pOSLCllAcc.iCallAccessor: Creating list. Call Nick.");
- err = AECreateList( NULL, 0, false, value ) ;
- }
- else
- err = errAENoSuchObject ; // was errAEEmptyListContainer: fixes LLD-UPG-??? */
- return err ;
- }
- }
-
- // If this is a range, then create a new range specifier in which any
- // 'ccnt' descriptors are replaced with the token representing the
- // actual container. Do not dispose the previous range specifier. The
- // new one we create exists only as long as it takes to make this
- // call. The old one still lives in other data structures, which will
- // need to be allowed to do the disposal
-
- if ( form == formRange )
- {
- FailErr( SubstContainerForccnt( container, containerClass,
- &selectionData ), err, errExit ) ;
- madeACopy = true ;
- }
- else
- madeACopy = false ;
-
- // try the application specific dispatch first
- // err = TryAccessor( GetGlobalRef(), &iFoundIt, container, wantType,
- // selectionData, containerClass, form, value ) ;
-
- err = GetCurrentContext(&curContext);
- if (!err)
- err = RecursiveCallObjectAccessor(wantType, container, containerClass,
- form, selectionData, value,
- &iFoundIt, &curContext);
-
- if ( err == errAEEventNotHandled )
- err = TryAccessor(GetSysGlobal(), &iFoundIt, container, wantType,
- selectionData, containerClass, form, value ) ;
- if ( (err == errAEEventNotHandled) && (! iFoundIt) )
- err = errAEAccessorNotFound ;
-
- if ( madeACopy )
- IgnoreOSErr( AEDisposeDesc( &selectionData ) ) ;
-
-
- FAIL_ERR_PROC(err,errExit)
- END_FAIL_ERR_PROC(err)
-
- } /* iCallAccessor */
-
- //———————————————————————— iAEGetObjectAccessor ————————————————————————
- pascal OSErr
- iAEGetObjectAccessor( DescType desiredClass,
- DescType containerType,
- OSLAccessorUPP *handler,
- long *handlerRefcon,
- Boolean isSysHandler)
-
- {
- ObjectAccessorKey key ;
- ObjectAccessorValue theValue ;
- GlobalRecHandle properGlobal ;
- OSErr out;
-
- // NEED TO IMPLEMENT THIS TO CALL THROUGH CONTEXTS
- DebugStr("\pOSLClAcc.iAEGetObjectAccessor: No good. Exit to shell, please.");
-
- out = noErr;
-
- if ( isSysHandler )
- properGlobal = GetSysGlobal() ;
- else
- properGlobal = GetGlobalRef() ;
-
- key.firstKey = desiredClass;
- key.secondKey = containerType;
-
- out = AEGetKeyValue( (*properGlobal)->accessorHashTable,
- NULL, (KeyPtr)&key, (HEntryPtr)&theValue ) ;
-
- if ( out == noErr )
- {
- *handler = theValue.handler ;
- *handlerRefcon = theValue.handlerRefcon ;
- }
-
- return out ; //<eeh> these hash mgr errors may require translation
- }
-
-
-
- //———————————————————————— iAEInstallObjectAccessor ————————————————————————}
- pascal OSErr
- iAEInstallObjectAccessor(DescType desiredClass ,
- DescType containerType ,
- OSLAccessorUPP handler ,
- long handlerRefcon ,
- Boolean isSysHandler)
-
- {
- ObjectAccessorKey key;
- ObjectAccessorValue theValue;
- GlobalRecHandle properGlobal;
-
- // NEED TO IMPLEMENT THIS TO CALL THROUGH CONTEXTS
- DebugStr("\pOSLClAcc.iAEInstallObjectAccessor: No good. Exit to shell, please.");
-
- // CHECK PASCAL CODE!!!! should "|" below be "||"? I think so.
- // add check for non-nil and non-odd handler
- if ( ( handler == NULL ) || ( (long)handler & 1) ) //if it's nil or odd... (this is stupid) ...fixes LLD-UPG-4 and -5
- {
- return paramErr ;
- }
-
- if ( isSysHandler )
- properGlobal = GetSysGlobal() ;
- else
- properGlobal = GetGlobalRef() ;
-
- key.firstKey = desiredClass;
- key.secondKey = containerType;
- theValue.handler = handler;
- theValue.handlerRefcon = handlerRefcon;
-
- // <eeh> do I need to translate this error?
- return AEReplaceEntry( (*properGlobal)->accessorHashTable, NULL,
- (KeyPtr)&key, (HEntryPtr)&theValue ) ;
- }
-
-
- //———————————————————————— iAERemoveObjectAccessor ————————————————————————
- pascal OSErr
- iAERemoveObjectAccessor( DescType desiredClass ,
- DescType containerType ,
- OSLAccessorUPP handler ,
- Boolean isSysHandler)
- {
- ObjectAccessorKey key ;
- ObjectAccessorValue theValue ;
- GlobalRecHandle properGlobal ;
- OSErr out ;
-
- // NEED TO IMPLEMENT THIS TO CALL THROUGH CONTEXTS
- DebugStr("\pOSLClAcc.iAERemoveObjectAccessor: No good. Exit to shell, please.");
-
- out = noErr;
-
- if ( isSysHandler )
- properGlobal = GetSysGlobal() ;
- else
- properGlobal = GetGlobalRef() ;
-
- key.firstKey = desiredClass ;
- key.secondKey = containerType ;
-
- out = AEGetKeyValue( (*properGlobal)->accessorHashTable,
- NULL, (KeyPtr)&key, (HEntryPtr)&theValue ) ;
-
- // was checking both in same IF, and returning noErr though refusing
- // to install if the ptrs didn't match. 2/3
-
- if ( out == noErr ) // added 3/10
- {
- if ( (handler != nil) && (handler != theValue.handler) ) // fixes LLD-UPG-7
- out = errAEAccessorNotFound ; // changed from handlerNotFound as per LLD??? (comment)
- else // IF out = NoErr THEN
- out = AERemoveKeyEntry( (*properGlobal)->accessorHashTable,
- NULL, (KeyPtr)&key) ;
- }
- return out ; // <eeh> these hash mgr errors may require translation
- }
-
-